
#include <BLabel>
#include <BFile>
#include <BReadWrite>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BFileDialog>
#include <BMessageBox>

#include "TerrainPanel.h"

TerrainPanel::TerrainPanel(BWidget* parent) : BGroupBox(parent)
{
	this->setTitle("Terrain");

	BGridLayout* gridLayout = new BGridLayout();
	{
		BLabel* optimizedLabel = new BLabel("optimized");
		_optimizedCheckBox = new BCheckBox();

		BLabel* alignLabel = new BLabel("align");
		_alignComboBox = new BComboBox();
		_alignComboBox->addItem("center", Align_VCenter | Align_HCenter);
		_alignComboBox->addItem("left-bottom", Align_Left | Align_Bottom);
		_alignComboBox->addItem("left-center", Align_LeftCenter);
		_alignComboBox->addItem("left-top", Align_Left | Align_Top);
		_alignComboBox->addItem("right-bottom", Align_Right | Align_Bottom);
		_alignComboBox->addItem("right-center", Align_Right | Align_VCenter);
		_alignComboBox->addItem("right-top", Align_Right | Align_Top);
		_alignComboBox->addItem("top-center", Align_Top | Align_HCenter);
		_alignComboBox->addItem("bottom-center", Align_Bottom | Align_HCenter);

		BLabel* widthLabel = new BLabel("width");
		_widthSpinBox = new BRealSpinBox();
		_widthSpinBox->setFormulable(true);

		BLabel* heightLabel = new BLabel("height");
		_heightSpinBox = new BRealSpinBox();
		_heightSpinBox->setFormulable(true);

		BLabel* widthSegmentLable = new BLabel("width-segments");
		_widthSegmentSpinBox = new BSpinBox(0, 9999);
		_widthSegmentSpinBox->setButtonShown(true);

		BLabel* heightSegmentLabel = new BLabel("height-segments");
		_heightSegmentSpinBox = new BSpinBox(0, 9999);
		_heightSegmentSpinBox->setButtonShown(true);

		gridLayout->setWidget(0, 0, optimizedLabel);
		gridLayout->setWidget(0, 1, _optimizedCheckBox);
		gridLayout->setWidget(1, 0, alignLabel);
		gridLayout->setWidget(1, 1, _alignComboBox);
		gridLayout->setWidget(2, 0, widthLabel);
		gridLayout->setWidget(2, 1, _widthSpinBox);
		gridLayout->setWidget(3, 0, heightLabel);
		gridLayout->setWidget(3, 1, _heightSpinBox);
		gridLayout->setWidget(4, 0, widthSegmentLable);
		gridLayout->setWidget(4, 1, _widthSegmentSpinBox);
		gridLayout->setWidget(5, 0, heightSegmentLabel);
		gridLayout->setWidget(5, 1, _heightSegmentSpinBox);
	}

	BVBoxLayout* layout = new BVBoxLayout(this);
	layout->addLayout(gridLayout);

	connect(this, Signal_AssetChanged, &TerrainPanel::slotAssetChanged);
	connect(_optimizedCheckBox, Signal_Toggled, &TerrainPanel::slotOptimizedToggled);
	connect(_alignComboBox, Signal_ItemClicked, &TerrainPanel::slotAlignEdited);
	connect(_widthSpinBox, Signal_EditFinished, &TerrainPanel::slotSizeEdited);
	connect(_heightSpinBox, Signal_EditFinished, &TerrainPanel::slotSizeEdited);
	connect(_widthSegmentSpinBox, Signal_EditFinished, &TerrainPanel::slotSegmentEdited);
	connect(_heightSegmentSpinBox, Signal_EditFinished, &TerrainPanel::slotSegmentEdited);
}
TerrainPanel::~TerrainPanel()
{

}

void TerrainPanel::slotAssetChanged(BObject* object, const BValue& value)
{
	_terrain = (BTerrain*)value;
	if (_terrain)
	{
		_optimizedCheckBox->setChecked(_terrain->optimized());
		_alignComboBox->setValue(_terrain->align());
		_widthSpinBox->setValue(_terrain->width());
		_heightSpinBox->setValue(_terrain->height());
		const BFloatTable& elevation = _terrain->elevation();
		_widthSegmentSpinBox->setValue(elevation.column());
		_heightSegmentSpinBox->setValue(elevation.row());
	}
	_widthSpinBox->setEnabled(_terrain);
	_heightSpinBox->setEnabled(_terrain);
	_widthSegmentSpinBox->setEnabled(_terrain);
	_heightSegmentSpinBox->setEnabled(_terrain);
}

void TerrainPanel::slotOptimizedToggled(BObject* object, const BValue& value)
{
	bool checked = value;
	_terrain->setOptimized(checked);
	emit("change-shape", _terrain);
}
void TerrainPanel::slotAlignEdited(BObject* object, const BValue& value)
{
	const BValue& v = _alignComboBox->value();
	Align align = _alignComboBox->value();
	_terrain->setAlign(align);
	emit("change-shape", _terrain);
}
void TerrainPanel::slotSizeEdited(BObject* object, const BValue& value)
{
	BReal width = _widthSpinBox->value();
	BReal height = _heightSpinBox->value();
	if (_terrain)
	{
		_terrain->setWidth(width);
		_terrain->setHeight(height);
		emit("change-shape", _terrain);
	}
}
void TerrainPanel::slotSegmentEdited(BObject* object, const BValue& value)
{
	int widthSegment = _widthSegmentSpinBox->value();
	int heightSegment = _heightSegmentSpinBox->value();
	if (_terrain)
	{
		BRealTable& elevation = _terrain->elevation();
		elevation.setColumn(widthSegment);
		elevation.setRow(heightSegment);
		emit("change-shape", _terrain);
	}
}
